﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

using System.Linq.Expressions;

namespace Husb.Data
{
    public abstract class ServiceBase<TRepository, T> : IRepository<T>
        where T : class
        where TRepository: IRepository<T> 
    {
        private readonly TRepository repository;
        private readonly IUnitOfWork unitOfWork;

        public ServiceBase(TRepository repository, IUnitOfWork unitOfWork)
        {
            this.repository = repository;
            this.unitOfWork = unitOfWork;
        }

        #region IRepository<T>

        public virtual void Add(T entity)
        {
            repository.Add(entity);
            Save();
        }

        public virtual void Update(T entity)
        {
            repository.Update(entity);
            Save();
        }

        public virtual void Delete(T entity)
        {
            repository.Delete(entity);
            Save();
        }

        public virtual void Delete(Expression<Func<T, bool>> where)
        {
            repository.Delete(where);
            Save();
        }

        public virtual T GetById(long id)
        {
            return repository.GetById(id);
        }

        public virtual T GetById(string id)
        {
            return repository.GetById(id);
        }

        public virtual int Count(Expression<Func<T, bool>> where = null)
        {
            return repository.Count(where);
        }

        //public virtual T Get(Expression<Func<T, bool>> where)
        //{
        //    throw new NotImplementedException();
        //}

        public virtual IEnumerable<T> GetAll()
        {
            return GetMany();
        }

        public virtual IEnumerable<T> GetMany(Expression<Func<T, bool>> where = null, Func<IQueryable<T>, IOrderedQueryable<T>> orderBy = null, string includeProperties = "")
        {
            return repository.GetMany(where, orderBy, includeProperties);
        }

        public T GetById(int id)
        {
            return repository.GetById(id);
        }

        public T GetById(Guid id)
        {
            return repository.GetById(id);
        }

        public IEnumerable<T> GetPaged(int maximumRows = 20, int startRowIndex = 0, Expression<Func<T, bool>> where = null, Func<IQueryable<T>, IOrderedQueryable<T>> orderBy = null, string includeProperties = "")
        {
            return repository.GetPaged(maximumRows, startRowIndex, where, orderBy, includeProperties);
        }

        public virtual void Save()
        {
            unitOfWork.Commit();
        }

        #endregion
    }
}
